/**
  ******************************************************************************
  * @file    LCD.c
  * @author  Dajin Li
  * @version V0.0.1
  * @date    08-08-2015 
  * @brief   This file contains LCD drivers function
  *              
  *          
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; KION(SZ) R&D Center
  *
  * Licensed under KION, (the "License");
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/

#include "lcd.h"

u8 bppselect = 1;

#define LCDCS1port          GPIOB
#define LCD_CS1             GPIO_Pin_7          //actlo - must be low for LCD to respond

#define LCDCS2port          GPIOC
#define LCD_CS2             GPIO_Pin_0          //actlo - must be low for LCD to respond

#define LCDDIport           GPIOC
#define LCD_DI              GPIO_Pin_1          //high data, low  instruction,high data

#define LCDRWport           GPIOC
#define LCD_RW              GPIO_Pin_2          //high read, low write,high read

#define LCDEport            GPIOC
#define LCD_E               GPIO_Pin_3          //enable, high enable, low disable

#define LCDRSTport          GPIOB
#define LCD_RST             GPIO_Pin_5          //high, take outof reset


#define LCDDataPort         GPIOA               //PA.0-PA.7 used as LCD data bus

#define LCDBkport           GPIOB
#define LCD_Bk              GPIO_Pin_6

#define nop_wait()          do{ __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
                              } while(0);



void lcd_memory_addr_control(u8 cmd);

u8 OLED_GRAM[8][128] = {0};


/**
* @brief    Writes the same byte across the display. If onoff = 0, the display is
*           cleared, else all pixels are tunred on.
*
* @param    u8  onoff == 0x00 lights-up the display, else all pixels on
* @note     none
* @retval   none
*
* 
*/

void LCDall(u8 onoff)
{

} 
#define DLY_CNT 5
void delay(u16 delay)
{
    u16 i = 0, j = 0;
    for(i = 0; i < delay; i++)
    {
        for(j = 0; j < 10; j++)
        {
            __NOP();
        }
    }
}


static void LCD_WriteCommand1(u8 cmd)
{
    delay(DLY_CNT);
    LCDCS1port->BRR = LCD_CS1;
    LCDDIport->BRR = LCD_DI;
    LCDEport->BSRR = LCD_E;
    LCDDataPort->BRR = (~cmd) & 0xff;
    LCDDataPort->BSRR = cmd;
    delay(DLY_CNT);
    LCDEport->BRR = LCD_E;
    delay(DLY_CNT);    
    LCDCS1port->BSRR = LCD_CS1;
}
static void  LCD_WriteData1(u8 data)
{
    delay(DLY_CNT);
    LCDCS1port->BRR = LCD_CS1;
    LCDDIport->BSRR = LCD_DI;
    LCDEport->BSRR = LCD_E;
    LCDDataPort->BRR = (~data) & 0xff;
    LCDDataPort->BSRR = data;
    delay(DLY_CNT);
    LCDEport->BRR = LCD_E;
    delay(DLY_CNT);
    LCDCS1port->BSRR = LCD_CS1;
}
static void  LCD_WriteCommand2(u8 cmd)
{
    delay(DLY_CNT);
    LCDCS2port->BRR = LCD_CS2;
    LCDDIport->BRR = LCD_DI;
    LCDEport->BSRR = LCD_E;
    LCDDataPort->BRR = (~cmd) & 0xff;
    LCDDataPort->BSRR = cmd;
    delay(DLY_CNT);
    LCDEport->BRR = LCD_E;
    delay(DLY_CNT);
    LCDCS2port->BSRR = LCD_CS2;
}
static void  LCD_WriteData2(u8 data)
{
    delay(DLY_CNT);
    LCDCS2port->BRR = LCD_CS2;
    LCDDIport->BSRR = LCD_DI;
    LCDEport->BSRR = LCD_E;
    LCDDataPort->BRR = (~data) & 0xff;
    LCDDataPort->BSRR = data;
    delay(DLY_CNT);
    LCDEport->BRR = LCD_E;
    delay(DLY_CNT);
    LCDCS2port->BSRR = LCD_CS2;
}




/**
* @brief    Initializes the 320x240 LCD using the NJU6815 chip.
            This function will require modifications for the 320x240 B&W module.
*           This function assumes and creates '80 type CPU waveforms. Additionally, it 
*           assumes that power was applied and is stable, duty at 1/128, boost Vdd to 6.
* @param    none
* @note     none
* @retval   none
*/
void LCD_init(void)
{
    GPIO_SetBits(LCDBkport, LCD_Bk);
    GPIO_SetBits(LCDRSTport,LCD_RST);
    delay(120);
    LCD_WriteCommand1(0xc0);        
    LCD_WriteCommand2(0xc0);        
    LCD_WriteCommand1(0x3f);        
    LCD_WriteCommand2(0x3f); 
    test_pattern(0x00);
  
} /* end of LCD15_init() */
/**
* @brief    Writes to the LCD a checker pattern starting at row/colum 0/0.
* @param    u8  row: defines the horizontal pixel where to move the cursor.
* @note     none
* @retval   none
*/
void test_pattern(u8 pattern)
{
    int i,j,x;
    for (j=0; j<8; j++)
    {
        for (i=0; i<128; i++)
        {       
            x=i;
            if(x<64)
            {

                LCD_WriteCommand1(0xB8+j);
                LCD_WriteCommand1(0x40+x);
                LCD_WriteData1(0x00);
            }
            else    
            {
                x=x-64;
                LCD_WriteCommand2(0xB8+j);
                LCD_WriteCommand2(0x40+x);
                LCD_WriteData2(0x00);
            }
        }
    }
}
void clear_status_menu_zone(void)
{

}


/**
* @brief    Writes the icon pointed by str to the display at the specified x,y coordinates.
*           This routine will work for any size image as long as the image will fit in the 
*           box drawn. Image width/height must be column-2 and row-2 otherwise the image 
*           will be cut off or will not fully fill the box. Sets the horizontal autoincrement
*           on.
*           CAUTION: If the column crosses the end of the row, the rest of the pixels will
*           show at the beginning of the next row.
*           CAUTION: this routine will only work with images of u8-width increments. It
*           must be called with "u8+2" width increments to account for the border.
* @param    s16 row
* @param    s16 column
* @param    u8 width
* @param    u8 height
* @param    u8 *str: pointer to the image
* @note     none
* @retval   none
*/
void LCD_wr_icon(s16 row, s16 column, s16 width, s16 height, u8 invert, u8 *str, u8 gray)
{

}
/**
* @brief    Writes the icon pointed by str to the display at the specified x,y coordinates.
*           This routine will work for any size image as long as the image will fit in the 
*           box drawn. Image width/height must be column-2 and row-2 otherwise the image 
*           will be cut off or will not fully fill the box. Sets the horizontal autoincrement
*           on.
*           CAUTION: If the column crosses the end of the row, the rest of the pixels will
*           show at the beginning of the next row.
*           CAUTION: this routine will only work with images of u8-width increments. It
*           must be called with "u8+2" width increments to account for the border.
* @param    s16 row
* @param    s16 column
* @param    u8 width
* @param    u8 height
* @param    u8 *str: pointer to the image
* @note     none
* @retval   none
*/
void LCD_wr_icon_gray(s16 row, s16 column, s16 width, s16 height, u8 invert, u8 *str, u8 gray)
{

}
void LCD_wr_icon_gray_special(s16 row, s16 column, s16 width, s16 height, u8 invert, u8 *str, u8 gray)
{

}
void LCD_wr_icon_gray_zone(s16 row, s16 column, s16 width, u8 invert, u8 *str, u8 gray, u16 start_col, u16 end_col)
{

}
/**
* @brief    set column address.
* @param    u16 column
* @note     none
* @retval   none
*/
void lcd_column_set(s16 column)
{


}
/**
* @brief    Sets page address.
* @param    u8 page
* @note     none
* @retval   none
*/
void lcd_page_addr_set(s16 page)
{

}
/**
* @brief    lcd memory control.
* @param    u8 cmd
* @note     none
* @retval   none
*/
void lcd_memory_addr_control(u8 cmd)
{
}

void LCD_hw_clear(u16 row, u16 column, u16 height,u16 width, u8 gray)
{

}
void LCD_draw_line(u16 row, u16 column, u16 height,u16 width, u8 invert, u8 gray)
{
}
void LCD_clear_zone(u16 start_col, u16 end_col)
{
}

void LCD_wr_zone(s16 row, s16 column, s16 width, s16 height, u8 gray)
{

}

void lcd_refresh(void)
{
    int i,j,x;
    for (j = 0; j < 8; j ++)
    {
        for (i = 0; i < 128; i ++)
        {       
            x = i;
            if(x < 64)
            {
                x = 63 - x;
                LCD_WriteCommand2(0xB8 + (7 - j));  
                LCD_WriteCommand2(0x40 + x);                
                LCD_WriteData2(OLED_GRAM[j][i]);
            }
            else    
            {       
                LCD_WriteCommand1(0xB8 + (7 - j));  
                LCD_WriteCommand1(0x40 + 127 - x);  
                LCD_WriteData1(OLED_GRAM[j][i]);
            }
        } 
    }
}


